import logging
import datetime

from celery import shared_task

from .edu_admin import NewEducationAdminister
from .models import StudentInfo, CourseItem
from apps.schedule.models import Course as ScheduleCourse
from apps.Course import edu_admin

logger = logging.getLogger("pioneer_xiaoke")


@shared_task()
def get_course_item(student_info_id: int):
    """拉取教务系统课表并写入数据库。"""
    logger.info("Starting to create course item for %s", student_info_id)

    try:
        student_info = StudentInfo.objects.get(id=student_info_id)
    except StudentInfo.DoesNotExist:
        logger.warning("StudentInfo not found, id=%s", student_info_id)
        return

    student_id, student_password = student_info.student_id, student_info.student_password

    # 登录教务系统
    user_edu_admin = NewEducationAdminister(student_id, student_password)
    login_msg = user_edu_admin.login()
    if login_msg:
        student_info.message = login_msg
        student_info.save(update_fields=["message", "updated_at"])
        logger.info("Login failed for %s: %s", student_id, login_msg)
        return

    # 获取用户的课表信息
    try:
        course_items = user_edu_admin.get_user_course_item()
    except Exception as exc:  # pylint: disable=broad-except
        student_info.message = f"获取课表失败：{exc}"
        student_info.save(update_fields=["message", "updated_at"])
        logger.exception("Fetching course items failed for %s", student_id)
        return

    for course_item in course_items:
        CourseItem.objects.create(
            student=student_info,
            course_id=course_item[0],
            name=course_item[1],
            order=course_item[4],
            credit=course_item[5],
            property=course_item[6],
            category=course_item[7],
            exam_type=course_item[8],
            teacher=course_item[9],
            method=course_item[10],
            select_status=course_item[11],
            course_time=course_item[12],
            location=course_item[13],
        )

    student_info.message = f"共获取到 {len(course_items)} 条课表信息，已保存您的课程表信息。"
    student_info.save(update_fields=["message", "updated_at"])
    logger.info("Course items saved for %s, count=%s", student_id, len(course_items))

    # 将课表同步到 schedule.Course
    if student_info.user:
        _sync_schedule_courses(student_info)
        logger.info("Synced schedule courses for user=%s", student_info.user_id)


def _sync_schedule_courses(student_info: StudentInfo):
    """将 CourseItem 转存到 schedule.Course，覆盖当前用户原有课程。"""
    user = student_info.user
    # 清空用户原有课程，避免重复
    ScheduleCourse.objects.filter(user=user).delete()

    course_items = CourseItem.objects.filter(student=student_info)
    schedule_courses = []
    for item in course_items:
        payload = _build_schedule_payload(item, user)
        schedule_courses.append(ScheduleCourse(**payload))

    if schedule_courses:
        ScheduleCourse.objects.bulk_create(schedule_courses)


def _build_schedule_payload(item: CourseItem, user):
    course_time = item.course_time or ""
    weeks = edu_admin.extract_weeks(course_time) or [1]
    weekday = edu_admin.extract_weekday(course_time) or 1
    periods = edu_admin.extract_periods(course_time) or [1, 1]
    start_period, end_period = periods[0], periods[-1]

    start_time_str = edu_admin.course_start_time_dict.get(start_period, "08:00")
    end_time_str = edu_admin.course_start_time_dict.get(end_period, "08:45")

    start_time = datetime.datetime.strptime(start_time_str, "%H:%M").time()
    end_time = datetime.datetime.strptime(end_time_str, "%H:%M") + datetime.timedelta(minutes=45)
    end_time = end_time.time()

    return {
        "user": user,
        "course_name": item.name,
        "teacher": item.teacher or "",
        "location": item.location or "",
        "weekday": weekday,
        "start_time": start_time,
        "end_time": end_time,
        "start_week": min(weeks),
        "end_week": max(weeks),
        "class_number": item.course_id,
        "credit": item.credit or None,
        "notes": item.property or "",
        "reminder_enabled": True,
    }
